package org.jing.core.util;

import org.jing.core.lang.JingException;

import java.util.Arrays;

/**
 * Description: <br>
 *
 * @author bks <br>
 * @since 2021-07-21 <br>
 */
@SuppressWarnings({ "unused", "WeakerAccess", "StringBufferReplaceableByString" })
public class ByteUtil {
    private static final int[] DEC = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11,
        12, 13, 14, 15,
    };

    private static final byte[] HEX_BYTES = { (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5',
        (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e',
        (byte) 'f'
    };

    private static final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    public static int getDec(int index) {
        try {
            return DEC[index - '0'];
        }
        catch (ArrayIndexOutOfBoundsException ex) {
            return -1;
        }
    }

    public static byte getHex(int index) {
        return HEX_BYTES[index];
    }

    public static String toHexString(char c) {
        StringBuilder stbr = new StringBuilder(4);
        stbr.append(HEX_CHARS[(c & 0xf000) >> 12]);
        stbr.append(HEX_CHARS[(c & 0x0f00) >> 8]);
        stbr.append(HEX_CHARS[(c & 0xf0) >> 4]);
        stbr.append(HEX_CHARS[(c & 0x0f)]);
        return stbr.toString();
    }

    public static byte[] fromHexString(String input) {
        if (StringUtil.isEmpty(input)) {
            throw new JingException("empty string");
        }
        char[] inputChars = input.toCharArray();
        byte[] result = new byte[input.length() >> 1];
        for (int i$ = 0; i$ < result.length; i$++) {
            int upperNibble = getDec(inputChars[2 * i$]);
            int lowerNibble = getDec(inputChars[2 * i$ + 1]);
            if (upperNibble < 0 || lowerNibble < 0) {
                throw new JingException("non hx char found");
            }
            result[i$] = (byte) ((upperNibble << 4) + lowerNibble);
        }
        return result;
    }

    public static String toHexString(byte[] buffer) {
        StringBuilder stbr = new StringBuilder();
        for (byte b$ : buffer) {
            stbr.append(HEX_CHARS[b$ >>> 4 & 15]).append(HEX_CHARS[b$ & 15]);
        }
        return stbr.toString();
    }

    public static byte[] string2ByteArray(String content, String charset, int arrLength, byte fillByte) {
        try {
            byte[] buffer = StringUtil.ifEmpty(content).getBytes(charset);
            int length = buffer.length;
            if (arrLength < length) {
                buffer = Arrays.copyOfRange(buffer, 0, arrLength);
            }
            else if (arrLength > length) {
                buffer = Arrays.copyOf(buffer, arrLength);
                Arrays.fill(buffer, length, arrLength, fillByte);
            }
            return buffer;
        }
        catch (JingException e) {
            throw e;
        }
        catch (Throwable t) {
            throw new JingException(t, "invalid charset: {}", charset);
        }
    }
}
